package kgame5.k3d.core.obj3d.node3d {
import kgame5.k3d.core.math.Matrix3D;
import kgame5.k3d.core.math.Vertex3D;
import kgame5.k3d.core.obj3d.bound.AABB;
import kgame5.k3d.core.obj3d.bound.BBall;
import kgame5.k3d.core.obj3d.info.geometry.Face3D;
import kgame5.k3d.core.obj3d.info.geometry.GeometryInfo;
import kgame5.k3d.core.obj3d.info.material.MaterialInfo;
import kgame5.k3d.core.render.RenderSessionData;
import kgame5.k3d.core.render.layerrender.impl.Mesh3DLayerRender;
import kgame5.k3d.core.view3d.View3D;

import flash.display.BitmapData;

public class Mesh3D extends Node3D{
	
	//_____________________Property_________________________
	
	public var gi:GeometryInfo;//模型整体的信息，这个只是meshi才用
	public var mi:MaterialInfo;//材质,BestGroup3D和Loader是需要用这个的
	
	
	//_____________________Method__________________________
	public function Mesh3D(){
		//--
		super();
		renderer=new Mesh3DLayerRender();
	}
	
	//注意这个千万不能丢掉啊
	public function setGeometryInfo(gi:GeometryInfo):void{
		this.gi=gi;
		if(gi.aLine==null&&gi.aFace.length==0){
			throw new Error("必须是gi填充完毕再传进来，这样保证mi有数据");
		}
		//这个为了防止mi为null而做.直接原因是为了loader能更好的显示
		if(mi==null){
			mi=new MaterialInfo();
			mi.bmd=new BitmapData(2,2,false,0x00ff00);
			this.setMaterialInfo(mi);
		}
		
		//--由visu顶点得出的ABH
		ti.hardVO.aabb=AABB.CreateFromVertices(gi.aVertex);
		ti.hardVO.bball =BBall.CreateFromVertices(gi.aVertex);
	}
	
	public function setMaterialInfo(mi:MaterialInfo):void{
		this.mi=mi;
		if(gi==null){
			throw new Error("必须先设置gi");
		}
		
		//给每个face赋值
		for each(var face:Face3D in gi.aFace){
			face.mi=mi;
		}
	}
	//克隆
	public function clone():Mesh3D{
		var mesh:Mesh3D=new Mesh3D();
		mesh.setGeometryInfo(gi.clone());
		return mesh;
	}
	
	//返回的是模型的位置旋转缩放是否变了,
	override public function Update(rsd:RenderSessionData,isParentDirty:Boolean):void{
		
		//--
		if(isVisible()==false){
			return ;
		}
		
		//这个运算量还不是很高，只是matrix相乘，一次就可以了，不是matrix*很多个vertex
		ti.calcMoc_Full(parentNode.ti.Mow,rsd.Mwc, rsd.isMwcDirty,isParentDirty);
		
		//这个计算量较高,所以顶点都执行矩阵运算
		doProjectToScreen();
		
		//--
		if(renderer.aOuterFace!=null){//----补丁吧，为了处理融合三角面而使用
			renderer.render(gi,mi,ti,rsd);//这里只计算aScreen而不会去画
		}else{//常规做法，不使用融合三角形
			//--渲染,注意这个里的mc.clear()和重画是要生成很多对象的,消耗大量资源
			if(ti.isNeedRedraw) {
				//画
				renderer.render(gi,mi,ti,rsd);
			}
		}
	}
	
	//顶点投影，都投影到屏幕上
	private function doProjectToScreen():void{
		
		//var st1:int=getTimer();
		for each(var v:Vertex3D in gi.aVertex) {
			
			//1,投影到摄像机空间
			Matrix3D.SMul_Vertex_M(v, ti.Moc);
			//Matrix3D.SMul_Vertex_M(vv, Mf);//耻辱啊，曾经把Vertex3D的screenX共享了~~！！
			
			//2,投影到屏幕
			//！！注意现在还没有处理z为负的情况
			var t:Number=View3D.D/v.screenZ;
					
			//是有必要保存Screen的
			v.screenX=v.screenX*t;//screenX
			v.screenY=-v.screenY*t;//screenY
			//z不变，z用来排序
		}
		//session.stati.projectTime+=getTimer()-st1;
	}
}//end of class
}